package com.koron.ticket.spotcheck;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.PageHelper;
import com.koron.bean.base.Response;
import com.koron.bean.system.staff.vo.EamUser;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.ticket.enums.TicketEnum;
import com.koron.ticket.feign.ConfigureFeign;
import com.koron.ticket.feign.bean.PriorBean;
import com.koron.ticket.feign.bean.PriorQuery;
import com.koron.ticket.operation.mapper.OperationTicketMapper;
import com.koron.ticket.spotcheck.Spotcheckmapper.TicketSpotcheckMapper;
import com.koron.ticket.spotcheck.bean.*;
import com.koron.ticket.utils.StringUtils;
import com.koron.ticket.work.workticket.bean.WorkTicketQuery;
import com.koron.ticket.work.workticket.mapper.WorkTicketMapper;
import com.koron.ticket.work.workticket.service.WorkTicketService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.koron.ebs.mybatis.ADOConnection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: rocky
 * @Date: 2022/1/25 14:19
 */
@RestController
@RequestMapping("ticket/spotcheck")
@Api(tags = "两票管理-两票抽查")
public class TicketSpotcheckController {

    private String getCurrDs() {

        return ThreadLocalContext.get().getCurrDs();
    }

    private EamUser getEamUser() {
        return ThreadLocalContext.get();
    }

    @Autowired
    private ConfigureFeign configurefeign;

    @Autowired
    private WorkTicketService workticketservice;

    /**
     * 分页查询
     *
     * @param queryBean
     * @return Response
     * @version 1.0
     * @see Response
     */
    @PostMapping("getListAndPaging")
    @ApiOperation("分页查询")
    public Response getListAndPaging(@RequestBody WorkTicketQuery queryBean) {
        PageHelper.startPage(queryBean.getPage(), queryBean.getPageSize(), queryBean.getOrderBy());
        return ADOConnection.runTask(getCurrDs(), workticketservice, "getListAndPaging", Response.class, queryBean);
    }

    @PostMapping("/insert")
    @ApiOperation("新增抽查")
    public Response insert(@RequestBody TicketSpotcheckDto dto) {

        Assert.isFalse(StringUtils.isEmpty(dto.getTicketId()), "票据标识不能为空");
        Assert.isFalse(StringUtils.isEmpty(dto.getTicketType()), "票据类型不能为空");

        TicketSpotcheckBean bean = Convert.convert(TicketSpotcheckBean.class, dto);


        ADOConnection.runTask(getCurrDs(), factory -> {
            TicketSpotcheckMapper mapper = factory.getMapper(TicketSpotcheckMapper.class);
            String account = mapper.queryAccountByTicketIdOrderByCreateTime(dto.getTicketId());//原抽查人帐号

            //检查优先级
            if (!getTicketPrior(account, getEamUser().getAccount())) {
                Assert.isFalse(true, "抽查优先级不足够");
            }

            bean.setAccount(getEamUser().getAccount());
            bean.setName(getEamUser().getName());
            mapper.insertSelective(bean);
            if (bean.getTicketType().equals(TicketEnum.WORK.getValue())) {
                mapper.workUpdateCheckResultsById(bean.getCheckResults(), bean.getTicketId());
            }
            if (bean.getTicketType().equals(TicketEnum.OPERATION.getValue())) {
                mapper.operationUpdateCheckResultsById(bean.getCheckResults(), bean.getTicketId());
            }

            return bean.getTicketId();
        }, String.class);
        return Response.success(bean.getTicketId());
    }


    @GetMapping("/getListByWorkTicketId")
    @ApiOperation("获取票据所有抽查")
    public Response getListByWorkTicketId(@RequestParam String ticketId) {

        Assert.isFalse(StringUtils.isEmpty(ticketId), "票据标识不能为空");
        List<TicketSpotcheckBean> list = ADOConnection.runTask(getCurrDs(), factory -> {
            return factory.getMapper(TicketSpotcheckMapper.class).queryByTicketIdOrderByCreateTime(ticketId);
        }, List.class);

        return Response.success(list);
    }


    /**
     * 获取 两票抽查优先权
     * -99 没有权限抽查
     *
     * @param oldAccount
     * @param newAccount
     * @return
     */
    public Boolean getTicketPrior(String oldAccount, String newAccount) {

        PriorBean newpri = send(newAccount);

        //当前抽查人没有优先级
        if (ObjectUtil.isNull(newpri) || ObjectUtil.isNull(newpri.getTicketPrior())) {
            return false;
        }

        if (ObjectUtil.isAllNotEmpty(oldAccount, newpri)) {
            //判断两票抽查权重 是否不为正整数
            if (ObjectUtil.isNull(newpri.getTicketPrior())) {
                return false;
            }

            PriorBean oldpri = send(oldAccount);
            //判断 原抽查人权重 是否不为正整数
            if (ObjectUtil.isNull(oldpri.getTicketPrior())) {
                return true;
            }
            //原抽查人，优先级比当前人高
            if (oldpri.getTicketPrior().compareTo(newpri.getTicketPrior()) > 0) {
                return false;
            }
        }

        return true;
    }

    /**
     * 获取 业务配置 两票优先级
     *
     * @param account
     */
    public PriorBean send(String account) {
        PriorQuery priorFeignQuery = new PriorQuery(account);
        Response<List<PriorBean>> response = configurefeign.queryEquipmentDefectNums(priorFeignQuery);
        Assert.isFalse(response.getCode() != 200, response.getDescription());
        if (response.getCode() == 200) {
            List<PriorBean> list = response.getData();
            if (CollUtil.isNotEmpty(list)) {
                return list.get(0);
            }
        }
        return null;
    }


    @GetMapping("/otherCockpitTicket")
    @ApiOperation("公司驾驶舱-其他-两票")
    public Response otherCockpitTicket(@RequestParam("year") String year) {

        List<CockpitTicketVo> list = ADOConnection.runTask(getCurrDs(), factory -> {
            DateTime startTime = DateUtil.beginOfYear(DateUtil.parse(year, "yyyy"));
            DateTime endTime = DateUtil.endOfYear(DateUtil.parse(year, "yyyy"));
            List<WorkSpotBo> worklist = factory.getMapper(WorkTicketMapper.class).queryAllEffective(startTime, endTime);//所有有效的工作票
            List<OperSpotBo> operlist = factory.getMapper(OperationTicketMapper.class).queryAllEffective(startTime, endTime);//所有有效的操作票

            Map<String, List<WorkSpotBo>> unitmap = worklist.stream().filter(w -> w.getOrgName() != null).collect(Collectors.groupingBy(WorkSpotBo::getOrgName));//开票单位分组
            Map<String, List<OperSpotBo>> deptmap = operlist.stream().filter(w -> w.getOrgName() != null).collect(Collectors.groupingBy(OperSpotBo::getOrgName));//创建单位分组

            List<String> orglist = CollUtil.unionAll(unitmap.keySet(), deptmap.keySet());//所有部门
            Set<String> orgset = new HashSet<>(orglist);

            List<CockpitTicketVo> voList = new ArrayList();
            for (String orgName : orgset) {
                CockpitTicketVo cockpitTicketVo = new CockpitTicketVo();
                cockpitTicketVo.setName(orgName);
                List<WorkSpotBo> workSpotBos = Opt.ofNullable(unitmap.get(orgName)).orElse(new ArrayList<>());
                List<OperSpotBo> OperSpotBos = Opt.ofNullable(deptmap.get(orgName)).orElse(new ArrayList<>());
                int totalQty = workSpotBos.size() + OperSpotBos.size();
                long workpastqty = workSpotBos.stream().filter(w -> w.getCheckResults() == null || w.getCheckResults() == true).count();
                long operpastqty = OperSpotBos.stream().filter(w -> w.getCheckResults() == null || w.getCheckResults() == true).count();
                long pastTotalQty = workpastqty + operpastqty;
                BigDecimal divide = new BigDecimal(pastTotalQty).divide(new BigDecimal(totalQty), 2, BigDecimal.ROUND_UP);
                BigDecimal power = divide.multiply(new BigDecimal(100));
                cockpitTicketVo.setPower(power);
                voList.add(cockpitTicketVo);
            }
            return voList;
        }, List.class);

        return Response.success(list);
    }

}
